﻿using AntMovement.Core;
using AntMovement.Core.Entity;
using AntMovement.Core.Enum;
using AntMovement.Core.IParameter;
using AntMovement.Core.Logic.Base;
using AntMovement.Core.Manager;
using AntMovement.Menu.Device.Model;
using AntMovement.Parameter;
using Prism.Commands;
using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace AntMovement.Menu.Device.ViewModels
{
    public class IODemonstrationViewModel : IViewModelLife
    {
        public ObservableCollection<IOInfoModel> DISourc { get; set; }
        public ObservableCollection<IOInfoModel> DOSourc { get; set; }
        public TemporaryParameter Temporary { get; set; }
        public IOParameter IOP { get; set; }
        private IContainerProvider _containerProvider;
        private IDialogHost _dialogHost;
        private CancellationTokenSource _tokenSource;
        public IODemonstrationViewModel(ITemporaryParameter temporary, IIOParameter iOParameter, IContainerProvider containerProvider, IDialogHost dialogHost)
        {
            _tokenSource = new CancellationTokenSource();
            IOP = (IOParameter)iOParameter;
            Temporary = (TemporaryParameter)temporary;
            _containerProvider = containerProvider;
            DISourc = new ObservableCollection<IOInfoModel>();
            DOSourc = new ObservableCollection<IOInfoModel>();
            foreach (DI model in IOP.DIDataSet)
            {
                DISourc.Add(new IOInfoModel()
                {
                    CardNo = model.CardNo,
                    Id = model.Id,
                    Status = model.Status,
                    MdlIndex = model.MdlIndex,
                    Mdl = model.Mdl,
                    OrderlyNum = model.OrderlyNum,
                    Text = model.Text,
                });
            }
            foreach (DO model in IOP.DODataSet) 
            {
                DOSourc.Add(new IOInfoModel()
                {
                    CardNo = model.CardNo,
                    Id = model.Id,
                    Status = model.Status,
                    MdlIndex = model.MdlIndex,
                    Mdl = model.Mdl,
                    OrderlyNum = model.OrderlyNum,
                    Text = model.Text,
                });
            }
            ThreadPool.QueueUserWorkItem(new WaitCallback(sender =>
            {
                while (!_tokenSource.Token.IsCancellationRequested)
                {
                    for (int i = 0; i < DISourc.Count; i++)
                    {
                        DISourc[i].Status = IOP.DIDataSet[i].Status;
                    }
                    for (int i = 0; i < DOSourc.Count; i++)
                    {
                        DOSourc[i].Status = IOP.DODataSet[i].Status;
                    }
                    Thread.Sleep(80);
                }
            }));
            _dialogHost = dialogHost;
        }

        public DelegateCommand<ListViewItem> PreviewMouseLeftButtonUp => new DelegateCommand<ListViewItem>(sender =>
        {
            IOInfoModel info = sender.DataContext as IOInfoModel;
            if (info != null)
            {
                DO d = IOP.DODataSet.FirstOrDefault(x => x.Id == info.Id);
                if (d != null)
                {
                    ITemporaryParameter temporaryParameter = _containerProvider.Resolve<ITemporaryParameter>();
                    if (temporaryParameter.GetConnect())
                    {
                        bool bl = d.Status;
                        ICoil coil = GetCoil(d);
                        try
                        {
                            coil.Execute(!bl);
                        }
                        catch (Exception ex)
                        {
                            _dialogHost.DialogShow($"输出点执行异常:{ex}", LogLevel.Warning, hostDialog: PopUpType.Global);
                        }
                    }
                }
            }
        });

        private ICoil GetCoil(DO dO) 
        {
            switch (dO.Type)
            {
                case MotionType.PCI1230:
                    return new AntMovement.PCI1230.Logic.Coil(dO);
                case MotionType.SolidTech_E_SerialCard: 
                    return new AntMovernent.SolidTechESerialCard.Logic.Coil(dO);
                case MotionType.PCI9016:
                    return new AntMovement.PCI9016.Logic.Coil(dO);
                case MotionType.SMC308:
                    return new AntMovement.SDK.LTSMC.Logic.Coil(dO);
                case MotionType.SMC304:
                    return new AntMovement.SDK.LTSMC.Logic.Coil(dO);
            }
            return default;
        }

        public void Enter()
        {

        }

        public void Exit()
        {
            _tokenSource.Cancel();
        }
    }
}
